//
//  CHNetWork.swift
//  bridging_js
//
//  Created by cyptt on 2021/9/18.
//

import UIKit
import Alamofire

struct CHNetError{
    static let  ERROR_500 = "找不到服务器地址"  //500地址错误
    static let ERROR_404  = "404错误"  //404错误
    static let ERROR_401  = "权限错误"  //权限错误
    static let ERROR_OTHER  = "其他错误"  //其他错误
    static let ERROR_CANCEL = "取消了网络请求"  //取消了网络请求
    static let ERROR_OFFLINE = "网络离线!"  //网络离线
    static let ERROR_URLERROR = "服务器地址解析失败" //服务器地址解析失败
    static let ERROR_TIMEOUT = "请求超时!"
    static let ERROR_BAD = "请求网络异常!"
    static let ERROR_SERVER_BAD = "无法连接服务器!"
    static let ERROR_NO_JOSN = "返回值不为json"
}
public typealias SuccessBlock = ([String:Any]) -> Void
public typealias FailureBlock = (Error) -> Void
public typealias FailureStrB = (String ) -> Void
public typealias ProgressBlock = (Float) -> Void
public class CHAFNetRequest: NSObject {
    
    
    /*
     下载
     @saveFileName 如果传入文件名相同，者会覆盖原来的文件
     */
    public class func download(url:String,param:[String:Any]?,method:HTTPMethod,headers:HTTPHeaders,encoding:ParameterEncoding,queue:DispatchQueue?,saveFileName:String? = nil,success: @escaping SuccessBlock,failure:@escaping FailureStrB) {
        if param != nil {
            
        }
        
        if url.count == 0 {
            print("网络请求连接不正确")
            return;
        }
        let urlPath:URL = URL(string: url)!
        
        let headers:HTTPHeaders = headers
        
        //自定义下载地址
//        let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory,in: <#T##FileManager.SearchPathDomainMask#>,)
        let request = AF.download(urlPath,method:method,parameters: param,encoding: encoding, headers: headers)
        
        request.responseData { response in
 
            
#if DEBUG
            print(response)
            print(response.response?.statusCode)
            print("headers====",response.response?.headers)
            print(response.response?.headers["Content-Type"])
            print("fileURL",response.fileURL?.path)
            print("responsevalue===",response.value)
#else
#endif
           
            let contentType:String? = response.response?.headers["Content-Type"]
            switch response.result {
            case let .success(result):
                do {
                    print("result===",result)
                   
                  
                    if response.response?.statusCode == 200 {
                        /** 返回码处理 */
      
                        if contentType!.contains("image") || contentType!.contains("octet-stream") {
                            let documentPath =  NSTemporaryDirectory()
                            
                            var fileName:String?
                            if saveFileName == nil{
                                fileName = "\(getCurrentimeStamp())image.jpg"
                            }else{
                                fileName = saveFileName!
                            }
                            let endfile = documentPath.appending(fileName!)
                            
                            let filemanger=FileManager.init()
                            try? filemanger.removeItem(atPath: endfile)
                    
                            try? filemanger.copyItem(atPath: response.fileURL?.path ?? "", toPath: endfile)
                            if response.fileURL?.path != nil{
                                //删除环境路径
                                try? filemanger.removeItem(atPath: response.fileURL!.path)
                            }
     
                            let result = ["result_code":0,"result_msg":"成功","body":["filePath":endfile],"success":1]
                            success(result)
                        }else{
                      
                         
                            let resultJson:[String:Any]? = try?
                            JSONSerialization.jsonObject(with: result, options: .mutableContainers) as? [String : Any]
                            if resultJson != nil{
                                success(resultJson!)
                            }else{
                                failure("数据格式解析失败，非json")
                                
                            }

                        }
      
                    }else{
                        if contentType!.contains("image"){
                            //这里不处理
                            failure("数据格式解析失败，非json")
                        }else{
                      
    
                            let resultJson:[String:Any]? = try?
                            JSONSerialization.jsonObject(with: result, options: .mutableContainers) as? [String : Any]
                            
                            if resultJson != nil{
                                success(resultJson!)
                            }else{
                                failure("数据格式解析失败，非json")
                                
                            }
                        
                        }

                    }

                }
            case let .failure(error):

#if DEBUG
                print(error)
#else
#endif

                //注意这个地方要设置Localizations/简体中文
                let localDescriotion:String  = error.localizedDescription
                
                if (error.localizedDescription.contains("URLSessionTask failed with error:")){
                  let resultLocal =   localDescriotion.replacingOccurrences(of:"URLSessionTask failed with error:",with:"")
                    failure(resultLocal)
                }else{
                    failure(localDescriotion)
                }
               



            }
            
        }
//        request.responseURL { response in
//#if DEBUG
//            print(response)
//            print("response.result===",response.result)
//            print(response.response?.statusCode)
//            print(response.value)
//            print("response.metrics====",response.metrics)
//            print(response.fileURL?.path)
//#else
//
//
//
//#endif
//            switch response.result {
//            case let .success(result):
//                do {
//                    print("result===",result)
//                    print("result===",response.value)
//                    if response.response?.statusCode == 200 {
//                        /** 返回码处理 */
//
//                        print("fileURL",response.fileURL?.path)
//                        //从下临时的图片地址获取图片数据             //这个是下载下来的图片的临时存储地址，是一个file://XXX.temp文件，使用的时候需要吧file://去除掉，最好移动到一个能长久保存的地方
////                        var filestr=response.value!.absoluteString as String
////                        print("filestr",filestr)
////                        let startIndex = filestr.index(filestr.startIndex, offsetBy: 0)
////                        let endIndex = filestr.index(filestr.startIndex, offsetBy: 6)
////                        filestr.removeSubrange(startIndex...endIndex)
////                        print("filestr22==",filestr)
////                        // imagev.image=UIImage.init(contentsOfFile: filestr)
////
////                        //copy图片临时地址到新的地址
////                        //                                    let documentPath =  NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask,true).last
////                        let documentPath =  NSTemporaryDirectory()
////                        let endfile=documentPath.appending("\(getCurrentimeStamp())image.jpg")
////                        let filemanger=FileManager.init()
////                        try? filemanger.copyItem(atPath: filestr, toPath: endfile)
//
//                        let result = ["result_code":0,"result_msg":"成功","body":["filePath":response.fileURL?.path],"success":1]
//                        success(result)
//                    }else{
//
//
//                    }
//
//                }
//            case let .failure(error):
//
//#if DEBUG
//                print(error)
//#else
//
//
//#endif
//
//                //注意这个地方要设置Localizations/简体中文
//                let localDescriotion:String  = error.localizedDescription
//
//                if (error.localizedDescription.contains("URLSessionTask failed with error:")){
//                    let resultLocal =   localDescriotion.replacingOccurrences(of:"URLSessionTask failed with error:",with:"")
//                    failure(resultLocal)
//                }else{
//                    failure(CHNetError.ERROR_BAD)
//                }
//
//
//
//            }
//        }
    }
    public  static func getCurrentimeStamp()->String{
        let now = Date()
        
        let timeIntervarl:TimeInterval = now.timeIntervalSince1970
        let timestamp:Int = Int(timeIntervarl)
        print(timestamp)
        return String(timestamp)
    }

    public class func requestNet(url:String,param:[String:Any]?,method:HTTPMethod,headers:HTTPHeaders,encoding:ParameterEncoding,queue:DispatchQueue?,success: @escaping SuccessBlock,failure:@escaping FailureStrB) {
        if param != nil {
       
        }
     
        if url.count == 0 {
            print("网络请求连接不正确")
            return;
        }
        let urlPath:URL = URL(string: url)!
        
        let headers:HTTPHeaders = headers
     
        print("原始参数--",param)
        
        var finalEncoding = encoding
        if let param = param,
           encoding is URLEncoding,
           param.contains(where: { $0.value is [Any] }) {
            finalEncoding = URLEncoding(
                destination: .queryString,
                arrayEncoding: .noBrackets // 重要：去掉数组的方括号
            )
        }
        print(finalEncoding)
        print("最终参数",param)
        let request = AF.request(urlPath,method:method,parameters: param,encoding: finalEncoding, headers: headers)
      
        if queue != nil{
           
            request.responseJSON(queue:queue!) { (response1) in
          
                CHAFNetRequest.successResponse(response: response1  , success: success, failure: failure)
            }
        }else{
            request.responseJSON() { (response) in
             
                CHAFNetRequest.successResponse(response: response , success: success, failure: failure)
    
            }
        }
       
    }
    
    /*
     取消所有网络请求
     */
   static func cancelAllNet(){
        AF.session.getAllTasks { urlSessionTask in
            urlSessionTask.forEach { task in
                task.cancel()
            }
        }
    }
    
    private static func successResponse(response:AFDataResponse<Any>,success: @escaping SuccessBlock,failure:@escaping FailureStrB){
        if response.response?.statusCode == 500 {
  
            failure(CHNetError.ERROR_500)
            return
            
        }
        
//        if response.response?.statusCode == 401{
//            failure(CHNetError.ERROR_401)
//            return
//        }
        if response.response?.statusCode == 404{
            failure(CHNetError.ERROR_404)
            return
        }
        
        switch response.result {
        case let .success(result):
            do {
                
                let resultDict:[String:Any]? = result as? [String:Any]

                if response.response?.statusCode == 200 {
                    /** 返回码处理 */
        
                    if resultDict != nil{
                        success(resultDict!)
                    }else{
                        failure(CHNetError.ERROR_NO_JOSN)
                    }
                   
                }else{
//                    let resultDict:[String:Any] = result as! [String:Any]
                    if resultDict != nil{
                        success(resultDict!)
                    }else{
                        failure(CHNetError.ERROR_OTHER)
                    }
                
                }
             
            }
        case let .failure(error):
            
#if DEBUG
                print(error)
#else
                
                
#endif
          
         //注意这个地方要设置Localizations/简体中文
            let localDescriotion:String  = error.localizedDescription
            
            if (error.localizedDescription.contains("URLSessionTask failed with error:")){
              let resultLocal =   localDescriotion.replacingOccurrences(of:"URLSessionTask failed with error:",with:"")
                failure(resultLocal)
            }else{
                failure(localDescriotion)
            }
           
//            if error.localizedDescription.contains("cancelled"){
//                // 999
//                failure(CHNetError.ERROR_CANCEL)
//            }else if(error.localizedDescription.contains("The Internet connection appears to be offline")){
//                failure(CHNetError.ERROR_OFFLINE)
//            }else if(error.localizedDescription.contains("unsupported URL")){
//                failure(CHNetError.ERROR_URLERROR)
//            }else if(error.localizedDescription.contains("The request timed out")){
//                //-1001
//                failure(CHNetError.ERROR_TIMEOUT)
//            }else if (error.localizedDescription.contains("URLSessionTask failed with error")){
//                failure(CHNetError.ERROR_SERVER_BAD)
//            } else{
//
//                if error.localizedDescription.count > 0{
//                    failure(error.localizedDescription)
//                }else{
//                    failure(CHNetError.ERROR_BAD)
//                }
//
//            }
          
        }
        
    }
    //MARK: - POST请求 数组参数（由于有数组参数的需求 ）[["id":"1","value":""],["id":"2","value":""]]
    public class func POST2(url:String,param:Array<[String:String]>,success: @escaping SuccessBlock) {
   
        let urlPath:URL = URL(string: url)!

        let data = try? JSONSerialization.data(withJSONObject: param, options: [])
        var urlRequest = URLRequest(url: urlPath)
        urlRequest.httpMethod = "POST"
        urlRequest.httpBody = data
        urlRequest.allHTTPHeaderFields = ["application/json":"Accept","application/json;charset=UTF-8":"Content-Type"]
        
        let request = AF.request(urlRequest)
        request.responseJSON { (response) in
            DispatchQueue.global().async(execute: {
        
                switch response.result {
                case let .success(result):
                    do {
                        let resultDict:[String:Any] = result as! [String:Any]
                        DispatchQueue.main.async(execute: {
                            /** 返回码 (Int 类型code 会报崩) */
                            let code = resultDict["resp_code"]
                            var resp_code = 0
                            if code is String {
                                resp_code = Int(code as! String)!
                            } else if code is Int {
                                resp_code = code as! Int
                            }
                            switch resp_code {
                            case 0:
                                success(resultDict)
                            case 1: break
                            // SVProgressHUD.showError(withStatus: (resultDict["resp_msg"] as! String))
                            default: break
                            //SVProgressHUD.showError(withStatus: (resultDict["resp_msg"] as! String))
                            }
                        })
                    }
                case let .failure(error):
                    print(error)
                }
                
            })
            
        }
    }
    /**
     上传一个文件
     @param url 地址
     @param imageData 文件数据
     @param parameters 参数
     @param headers 请求头
     @param withName 文件参数名
     @param fileName 文件名
     
     */
    public class func uploadImage(url: String, imageData:Data?, parameters: [String : Any]?, headers:HTTPHeaders?,withName:String = "file",fileName:String? = nil,success: @escaping SuccessBlock, failure:@escaping FailureStrB){
        var mfileName:String?
        if fileName == nil{
            mfileName = "\(Date.init().timeIntervalSince1970).png"
        }else{
            mfileName = fileName!
        }

        AF.upload(multipartFormData: { multipartFormData in
            
            if parameters != nil {
                for (key, value) in parameters! {
                    if let temp = value as? String {
                        multipartFormData.append(temp.data(using: .utf8)!, withName: key)
                    }
                    if let temp = value as? Int {
                        multipartFormData.append("\(temp)".data(using: .utf8)!, withName: key)
                    }
                    if let temp = value as? NSArray {
                        temp.forEach({ element in
                            let keyObj = key + "[]"
                            if let string = element as? String {
                                multipartFormData.append(string.data(using: .utf8)!, withName: keyObj)
                            } else
                            if let num = element as? Int {
                                let value = "\(num)"
                                multipartFormData.append(value.data(using: .utf8)!, withName: keyObj)
                            }
                        })
                    }
                }
            }
          
            if let data = imageData{
               
                multipartFormData.append(data, withName: withName, fileName: mfileName!, mimeType: "image/png")
                
            }

    
        },
        to: url, method: .post , headers: headers)
        .responseJSON(completionHandler: { (response) in
            

            if response.response?.statusCode == 500 {
      
                failure(CHNetError.ERROR_500)
                return
                
            }
            
            if response.response?.statusCode == 401{
                failure(CHNetError.ERROR_401)
                return
            }
            if response.response?.statusCode == 404{
                failure(CHNetError.ERROR_404)
                return
            }
            switch response.result {
            case let .success(result):
                do {
                    if response.response?.statusCode == 200 {
                        
                        let resultDict:[String:Any] = result as! [String:Any]
                        /** 返回码处理 */
                        success(resultDict)
                      
                    }else{
                   
                        failure(CHNetError.ERROR_OTHER)
                  
                    }
                 
                }
            case let .failure(error):
                
                failure(error.localizedDescription)
            }
           
        }).uploadProgress(queue: .main, closure: { progress in
            //Current upload progress of file
      
        })
    }
    

    /*
     上传多个文件
     */
    
    public class func uploadImages(url: String, imageDatas: [Data]?, parameters: [String : Any]?, headers:HTTPHeaders?,withName:String = "file",fileName:String? = nil,success: @escaping SuccessBlock, failure:@escaping FailureStrB){
         
        var mfileName:String?
        if fileName == nil{
            mfileName = "\(Date.init().timeIntervalSince1970).png"
        }else{
            mfileName = fileName!
        }
         
         AF.upload(multipartFormData: { multipartFormData in
             if parameters != nil {
                 for (key, value) in parameters! {
                     if let temp = value as? String {
                         multipartFormData.append(temp.data(using: .utf8)!, withName: key)
                     }
                     if let temp = value as? Int {
                         multipartFormData.append("\(temp)".data(using: .utf8)!, withName: key)
                     }
                     if let temp = value as? NSArray {
                         temp.forEach({ element in
                             let keyObj = key + "[]"
                             if let string = element as? String {
                                 multipartFormData.append(string.data(using: .utf8)!, withName: keyObj)
                             } else
                             if let num = element as? Int {
                                 let value = "\(num)"
                                 multipartFormData.append(value.data(using: .utf8)!, withName: keyObj)
                             }
                         })
                     }
                 }
             }
            
             
            for i in 0 ..< imageDatas!.count {
            
                if let data:Data = imageDatas?[i] {
                    multipartFormData.append(data, withName: withName, fileName: mfileName, mimeType: "image/png")
                    
                }
            }
            
      
           
         },
         to: url, method: .post , headers: headers)
         .responseJSON(completionHandler: { (response) in
             
          
             if response.response?.statusCode == 500 {
       
                 failure(CHNetError.ERROR_500)
                 return
             }
             
             if response.response?.statusCode == 401{
                 failure(CHNetError.ERROR_401)
                 return
             }
             if response.response?.statusCode == 404{
                 failure(CHNetError.ERROR_404)
                 return
             }
             switch response.result {
             case let .success(result):
                 do {
                     if response.response?.statusCode == 200 {
                         
                         let resultDict:[String:Any] = result as! [String:Any]
                         /** 返回码处理 */
                         success(resultDict)
                       
                     }else{
                    
                         failure(CHNetError.ERROR_OTHER)
                   
                     }
                  
                 }
             case let .failure(error):
                 
                 failure(error.localizedDescription)
             }
         }).uploadProgress(queue: .main, closure: { progress in
             //Current upload progress of file
        
         })
     }
    

}



